/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package MainGame;

import FrameWork.Global;
import FrameWork.Models.*;
import FrameWork.NewCamera;
import GameObject.ChessPiece;
import GameState.MainGameWithAI;
import Manager.ResourceManager;
import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.opengl.util.texture.Texture;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;
import utils.Matrix;
import utils.MatrixOps;
import utils.POINT;
import utils.TextureLoader;
import utils.TimeUtils;
import utils.Vector3;

/**
 *
 * @author trong_000
 */
public class Chess implements GLEventListener, MouseListener, MouseMotionListener, KeyListener {

    // --------------------------------------------------------------------------------
    // Camera
    // --------------------------------------------------------------------------------
    NewCamera cam = new NewCamera();

    private int prevMouseX;
    private int prevMouseY;

    // --------------------------------------------------------------------------------
    // Animation
    // --------------------------------------------------------------------------------

    private long prevTime = 0;
    private long currTime = 0;
    private long lastFrameTime;
    // --------------------------------------------------------------------------------
    // Objects
   
    MainGameWithAI mAI;

    // --------------------------------------------------------------------------------

    private GLU glu = null;
    // --------------------------------------------------------------------------------

    
    @Override
    public void init(GLAutoDrawable drawable) {
        Global.getIns().drawable = drawable;
        GL2 gl = drawable.getGL().getGL2();
        glu = Global.glu;
        gl.glEnable(GL2.GL_DEPTH_TEST);
	gl.glShadeModel(GL2.GL_SMOOTH);
	gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
	gl.glEnable(GL2.GL_CULL_FACE);
	gl.glEnable(GL2.GL_NORMALIZE);
	gl.glMatrixMode(GL2.GL_PROJECTION);
	gl.glLoadIdentity();
	gl.glMatrixMode(GL2.GL_MODELVIEW);
	gl.glLoadIdentity();
        
       
	setLight(gl);
	gl.glMatrixMode(GL2.GL_MODELVIEW);
        
        lastFrameTime = System.nanoTime();
        mAI = new MainGameWithAI();
    }

    // --------------------------------------------------------------------------------

    @Override
    public void reshape(GLAutoDrawable drawable, //
        int x, int y, int w, int h) {

        GL2 gl = drawable.getGL().getGL2();

        gl.glViewport(0, 0, w, h);

        calculatePerspective(gl);
    }

    // --------------------------------------------------------------------------------

    private void calculatePerspective(GL2 gl) {
        gl.glMatrixMode(GL2.GL_PROJECTION);

        gl.glLoadIdentity();

        double nr = 0.5;
        double fr = 3 * (cam.dist - nr) + nr;

        glu.gluPerspective(60, 1, nr, fr);

        gl.glMatrixMode(GL2.GL_MODELVIEW);
    }

    // --------------------------------------------------------------------------------

    private long calculateDt() {  
        if(prevTime==0){
            prevTime = System.currentTimeMillis();            
        }
        else
            prevTime = currTime;
        currTime = System.currentTimeMillis();
        return currTime - prevTime;
        
    }

    // --------------------------------------------------------------------------------

   
    //---------------------------------------------------------------------------------
    private void update(float dt){
        
    }
    
    private void draw( GL2 gl){
        
    }
    @Override
    public void display(GLAutoDrawable drawable) {
        long frameTime = System.nanoTime();
	float deltaTime = (frameTime - lastFrameTime) / 1000000000.0f;
	lastFrameTime = frameTime; 
        
        GL2 gl = drawable.getGL().getGL2();
        
        calculatePerspective(gl);
        gl.glPushMatrix();
        gl.glLoadIdentity(); 
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);

        //glu.gluLookAt(eyeDstX, eyeDstY, eyeDstZ, 0, 0, 0, topX, topY, topZ);
        //cam.rotateAlpha(180);
        cam.update(glu);
        //update(deltaTime);
        mAI.update(deltaTime);
        Global.getIns().drawAxes();
        //Global.getIns().drawCube(tt, 1, 0, -1);
        //Global.getIns().drawCube(1, 2, 1);
        //chessBoardModel.opengldraw(gl, 0, -0.05f, 0, 1.1f);
        //draw(gl);
        mAI.render(gl);
        gl.glPopMatrix();
      }

    // --------------------------------------------------------------------------------

    
    
    // --------------------------------------------------------------------------------

    public void displayChanged(GLAutoDrawable drawable, //
        boolean modeChanged, boolean deviceChanged) {
      // Empty
    }

    private void setLight(GL2 gl) {

        gl.glEnable(GL2.GL_LIGHTING);
        float SHINE_ALL_DIRECTIONS = 1;
        float[] lightPos = { -30, 30, 30, SHINE_ALL_DIRECTIONS };
        float[] lightColorAmbient = { 0.02f, 0.02f, 0.02f, 1f };
        float[] lightColorSpecular = { 0.9f, 0.9f, 0.9f, 1f };

            // Set light parameters.
        gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_POSITION, lightPos, 0);
        gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_AMBIENT, lightColorAmbient, 0);
        gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_SPECULAR, lightColorSpecular, 0);
        gl.glLightfv(GL2.GL_LIGHT1, GL2.GL_DIFFUSE, lightColorSpecular, 0);
        gl.glEnable(GL2.GL_LIGHT1);

    }

   
    
    // --------------------------------------------------------------------------------
    // MouseListener
    // --------------------------------------------------------------------------------

    @Override
    public void mouseEntered(MouseEvent e) {
      // Empty
    }

    @Override
    public void mouseExited(MouseEvent e) {
      // Empty
    }

    @Override
    public void mousePressed(MouseEvent e) {
      prevMouseX = e.getX();
      prevMouseY = e.getY();
      //inSelectionMode = true;
      
      mAI.setMouseX(e.getX());
      mAI.setMouseY(e.getY());
      mAI.setIsSelectionMode(true);
      cam.mousePressed(e);
    }

    @Override
    public void mouseReleased(MouseEvent e) {
      // Empty
    }

    @Override
    public void mouseClicked(MouseEvent e) {
      // Empty
    }

    // --------------------------------------------------------------------------------
    // MouseMotionListener
    // --------------------------------------------------------------------------------

    @Override
    public void mouseDragged(MouseEvent e) {
        cam.mouseDragged(e);
        int x = e.getX();
        int y = e.getY();
        Dimension size = e.getComponent().getSize();

        float thetaY = 360.0f * ((float) (prevMouseX - x) / (float) size.width);
        float thetaX = 360.0f * ((float) (prevMouseY - y) / (float) size.height);

        prevMouseX = x;
        prevMouseY = y;

        
    }

    // --------------------------------------------------------------------------------

    @Override
    public void mouseMoved(MouseEvent e) {
      // Empty
    }

    // --------------------------------------------------------------------------------
    // KeyListener
    // --------------------------------------------------------------------------------

    @Override
    public void keyTyped(KeyEvent evt) {
        switch (evt.getKeyChar()) {
          case 'A' :
          case 'a' :
            if (cam.dist <= 10) {
              cam.dist *= 2;
            }
            break;
          case 'Z' :
          case 'z' :
            if (cam.dist >= 5) {
              cam.dist /= 2;
            }
            break;
        }
    }

    // --------------------------------------------------------------------------------

    @Override
    public void keyPressed(KeyEvent e) {
      //  Empty    
    }

    // --------------------------------------------------------------------------------

    @Override
    public void keyReleased(KeyEvent e) {
      // Empty    
    }

    // --------------------------------------------------------------------------------

    public static void main(String[] args) {
        Frame frame = new Frame(Global.title);

        GLCanvas canvas = new GLCanvas();

        FPSAnimator animator = new FPSAnimator(canvas, 120);
        Chess chess = new Chess();
        canvas.addGLEventListener(chess);
        canvas.addMouseListener(chess);
        canvas.addMouseMotionListener(chess);
        canvas.addKeyListener(chess);
        animator.start();

        frame.add(canvas);
        frame.setSize(Global.wndWidth, Global.wndHeight);
        frame.setVisible(true);

        frame.addWindowListener(new WindowAdapter() {
          @Override
          public void windowClosing(WindowEvent e) {
            System.exit(0);
          }
        });
    }

    @Override
    public void dispose(GLAutoDrawable drawable) {
        
    }
}
